#pragma once
#include "Point3d.h"
#include "Vector3d.h"
#include <exception>
namespace Geometry
  {
  Point3d::Point3d()
    : m_x(0.0), m_y(0.0), m_z(0.0)
    {
    
    }

  Point3d::Point3d(double i_x, double i_y, double i_z)
    : m_x(i_x), m_y(i_y), m_z(i_z)
    {

    }

  double Point3d::operator[](size_t i_index) const
    {
    if (i_index > 2)
      {
      throw std::exception("Vector3d operator[]: argument out of range");
      }
    switch (i_index)
      {
      case 0:
        return m_x;
      case 1:
        return m_y;
      case 2:
        return m_z;
      default:
        throw std::exception("Vector3d operator[]: unsupported case");
      }
    }

  Point3d& Point3d::operator+=(const Vector3d& i_vector)
    {
    m_x += i_vector[0];
    m_y += i_vector[1];
    m_z += i_vector[2];
    return *this;
    }

  bool operator == (const Point3d& i_left, const Point3d& i_right)
    {
    return i_left[0] == i_right[0] && i_left[1] == i_right[1] && i_left[2] == i_right[2];
    }

  Point3d operator+(Point3d i_point, const Vector3d& i_vector)
    {
    return i_point += i_vector;
    }


  double determinant(const Point3d& i_pt_0, const Point3d& i_pt_1, const Point3d& i_pt_2)
    {
    double det =
      i_pt_0[0] * i_pt_1[1] * i_pt_2[2] +
      i_pt_0[1] * i_pt_1[2] * i_pt_2[0] +
      i_pt_1[0] * i_pt_2[1] * i_pt_0[2] -
      i_pt_0[2] * i_pt_1[1] * i_pt_2[0] -
      i_pt_1[0] * i_pt_0[1] * i_pt_2[2] -
      i_pt_2[1] * i_pt_1[2] * i_pt_0[0];
    return det;
    }

  Vector3d operator-(const Point3d& i_left, const Point3d& i_right)
    {
    return Vector3d(i_left[0] - i_right[0], i_left[1] - i_right[1], i_left[2] - i_right[2]);
    }


  }